#include "Time.hpp"

const string gpath = "/home/llllyrics/112_class";
int gprojid = 0X6666;
//操作系统，申请空间，是按照块为单位的：4kb，1kb，2kb，4mb.......
int gshmsize = 4096;
mode_t Gmode = 0600;//权限

const int CREATE = IPC_CREAT | IPC_EXCL | Gmode;
const int GET = IPC_CREAT;


class ShareMemory
{
private:
void CreateShmHelper(int flag)
    {
        //创建key
        _key = ftok(gpath.c_str(),gprojid);
        if(_key < 0)//创建失败
        {
            cerr<<"ftok error"<<endl;
            return;
        }
        //让server创建共享内存&&获取
        //注意：共享内存也有权限！在应用层和文件关联度不大，但是在底层和文件关联度大
        _shmid = shmget(_key,gshmsize,flag);//创建
        if(_shmid < 0)//创建失败
        {
            cerr<<"shmget error"<<endl;
            return;
        }
    }
public:
    ShareMemory():_shmid(-1),_key(0),_addr(nullptr){}
    ~ShareMemory(){}

    void CreateShm()
    {
        if(_shmid == -1)
            CreateShmHelper(CREATE);
    }
    void GetShm()
    {
        CreateShmHelper(GET);
    }
    void AttachShm()
    {
        //将共享内存挂接到自己的地址空间当中
        _addr = shmat(_shmid,nullptr,0);//将共享内存挂接到自己的虚拟地址上。
        if((long long)_addr == -1)return;//挂接失败返回nullptr
    }
    void DetachShm()
    {
        if(_addr != nullptr)
        shmdt(_addr);
        cout<<"detach done:"<<endl;
    }
    void DeleteShm()
    {
        int n = shmctl(_shmid,IPC_RMID,nullptr);
        if(n < 0) 
        {
            cout<<"delete failed"<<endl;
            return;
        }
        cout<<"delete shm done"<<endl;
    }
    void* GetAddr()
    {
        return _addr;
    }
    void ShmMeta()
    {
        struct shmid_ds buffer;//操作系统的数据类型
        //IPC_STAT表示
        int n = shmctl(_shmid,IPC_STAT,&buffer);
        if(n < 0)return;
        cout<<buffer.shm_atime<<endl;
        cout<<buffer.shm_cpid<<endl;
        cout<<buffer.shm_ctime<<endl;
        cout<<buffer.shm_perm.__key<<endl;
    }
private:
    int _shmid;
    key_t _key;
    void *_addr;
};
ShareMemory shm;